package simulador;

// Classe para geração de números aleatórios segundos várias distribuições
// Apenas a distribuição exponencial negativa está definida

public class Aleatorio {
    
    private double U1 = 0;
    private double U2 = 0;
    private double V1 = 0;
    private double V2 = 0;
    private double Y1 = 0;
    private double Y2 = 0;
    private int randStream = 1;
    private boolean togive = false;
    
    public Aleatorio(int stream){
        randStream = stream;
    }

	// Gera um número segundo uma distribuição exponencial negativa de média m
    public double exponencial (double m){
		return (-m*Math.log(RandomGenerator.rand64(randStream)));
	}
    
    public double gaussian (double m, double d){
        if(togive){
            togive = false;
            return m+(Y2*d);
        } else {
            U1=RandomGenerator.rand64(randStream);
            U2=RandomGenerator.rand64(randStream);
            V1 = 2.0 * U1 - 1;
            V2 = 2.0 * U2 - 1;
            double w = Math.pow(V1,2)+Math.pow(V2,2);
            if(w>1)
                return gaussian(m,d);
            else {
                Y1 = V1 * Math.sqrt((-2*Math.log(w))/w);
                Y2 = V2 * Math.sqrt((-2*Math.log(w))/w);
                togive=true;
                return m+(Y1*d);
            }
        }
    }
    
    public double uniform(double m, double d){
        return m+((d*2*RandomGenerator.rand64(randStream))-d);
    }
    
    public double nothing(){
        return RandomGenerator.rand64(randStream);
    }

}